From 87cb99a6dda5f1b5b0ace461757eae782a3d7873 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 20 Oct 2009 08:45:12 +0100 Subject: [PATCH] Add nomigrate config option to disable migration/restore The new nomigrate option can be set to non-zero in vm.cfg (for both hvm and pvm) to disallow a guest from being migrated or restored. (Save is still allowed for the purpose of checkpointing.) The option persists into a save file and is also communicated into the hypervisor, the latter for the purposes of a to-be-added hypercall for communicating to guests that migration is disallowed (which will be used initially for userland TSC-related sensing, but may find other uses). Signed-off-by: Dan Magenheimer --- tools/libxc/xc_domain.c | 9 +++++++++ tools/libxc/xenctrl.h | 2 ++ tools/python/xen/lowlevel/xc/xc.c | 21 +++++++++++++++++++++ tools/python/xen/xend/XendCheckpoint.py | 15 +++++++++++++-- tools/python/xen/xend/XendConfig.py | 4 ++++ tools/python/xen/xend/XendDomainInfo.py | 5 +++++ tools/python/xen/xm/create.py | 9 ++++++++- tools/python/xen/xm/xenapi_create.py | 1 + xen/arch/x86/domain.c | 3 +++ xen/arch/x86/domctl.c | 18 ++++++++++++++++++ xen/include/asm-x86/domain.h | 3 +++ xen/include/public/domctl.h | 7 +++++++ 12 files changed, 94 insertions(+), 3 deletions(-) diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 61cde9af39..f872583926 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -475,6 +475,15 @@ int xc_domain_set_tsc_native(int xc_handle, uint32_t domid, int is_native) return do_domctl(xc_handle, &domctl); } +int xc_domain_disable_migrate(int xc_handle, uint32_t domid) +{ + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_disable_migrate; + domctl.domain = (domid_t)domid; + domctl.u.disable_migrate.disable = 1; + return do_domctl(xc_handle, &domctl); +} + int xc_domain_memory_increase_reservation(int xc_handle, uint32_t domid, unsigned long nr_extents, diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index ea52fcc446..d6ecaf399c 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -630,6 +630,8 @@ int xc_domain_set_time_offset(int xc_handle, int xc_domain_set_tsc_native(int xc_handle, uint32_t domid, int is_native); +int xc_domain_disable_migrate(int xc_handle, uint32_t domid); + int xc_domain_memory_increase_reservation(int xc_handle, uint32_t domid, unsigned long nr_extents, diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index a1c39e48d5..12ea007a53 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -1485,6 +1485,20 @@ static PyObject *pyxc_domain_set_tsc_native(XcObject *self, PyObject *args) return zero; } +static PyObject *pyxc_domain_disable_migrate(XcObject *self, PyObject *args) +{ + uint32_t dom; + + if (!PyArg_ParseTuple(args, "i", &dom)) + return NULL; + + if (xc_domain_disable_migrate(self->xc_handle, dom) != 0) + return pyxc_error_to_exception(); + + Py_INCREF(zero); + return zero; +} + static PyObject *pyxc_domain_send_trigger(XcObject *self, PyObject *args, PyObject *kwds) @@ -2015,6 +2029,13 @@ static PyMethodDef pyxc_methods[] = { " is_native [int]: 1=native, 0=emulate.\n" "Returns: [int] 0 on success; -1 on error.\n" }, + { "domain_disable_migrate", + (PyCFunction)pyxc_domain_disable_migrate, + METH_VARARGS, "\n" + "Marks domain as non-migratable AND non-restoreable\n" + " dom [int]: Domain whose TSC mode is being set.\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + { "domain_send_trigger", (PyCFunction)pyxc_domain_send_trigger, METH_VARARGS | METH_KEYWORDS, "\n" diff --git a/tools/python/xen/xend/XendCheckpoint.py b/tools/python/xen/xend/XendCheckpoint.py index 146437c486..22f4fa6b42 100644 --- a/tools/python/xen/xend/XendCheckpoint.py +++ b/tools/python/xen/xend/XendCheckpoint.py @@ -226,6 +226,19 @@ def restore(xd, fd, dominfo = None, paused = False, relocating = False): else: dominfo = xd.restore_(vmconfig) + image_cfg = dominfo.info.get('image', {}) + is_hvm = dominfo.info.is_hvm() + + if is_hvm: + nomigrate = dominfo.info['platform'].get('nomigrate', 0) + else: + nomigrate = dominfo.info['platform'].get('nomigrate') + if nomigrate is None: + nomigrate = 0 + if int(nomigrate) != 0: + dominfo.destroy() + raise XendError("cannot restore non-migratable domain") + # repin domain vcpus if a target node number was specified # this is done prior to memory allocation to aide in memory # distribution for NUMA systems. @@ -248,8 +261,6 @@ def restore(xd, fd, dominfo = None, paused = False, relocating = False): assert console_port # if hvm, pass mem size to calculate the store_mfn - image_cfg = dominfo.info.get('image', {}) - is_hvm = dominfo.info.is_hvm() if is_hvm: apic = int(dominfo.info['platform'].get('apic', 0)) pae = int(dominfo.info['platform'].get('pae', 0)) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 84f1f0f556..b508fb45c0 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -146,6 +146,7 @@ XENAPI_PLATFORM_CFG_TYPES = { 'localtime': int, 'monitor': int, 'nographic': int, + 'nomigrate': int, 'pae' : int, 'rtc_timeoffset': int, 'serial': str, @@ -479,6 +480,9 @@ class XendConfig(dict): if 'tsc_native' not in self['platform']: self['platform']['tsc_native'] = 0 + if 'nomigrate' not in self['platform']: + self['platform']['nomigrate'] = 0 + if self.is_hvm(): if 'timer_mode' not in self['platform']: self['platform']['timer_mode'] = 1 diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index bf3c396ea4..1675cbd760 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -2464,6 +2464,11 @@ class XendDomainInfo: if arch.type == "x86" and hvm and viridian is not None: xc.hvm_set_param(self.domid, HVM_PARAM_VIRIDIAN, long(viridian)) + # If nomigrate is set, disable migration + nomigrate = self.info["platform"].get("nomigrate") + if arch.type == "x86" and nomigrate is not None and long(nomigrate) != 0: + xc.domain_disable_migrate(self.domid) + # Optionally enable virtual HPET hpet = self.info["platform"].get("hpet") if hvm and hpet is not None: diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 4c71587d3f..52b13a29d8 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -225,6 +225,10 @@ gopts.var('tsc_native', val='TSC_NATIVE', fn=set_int, default=0, use="""TSC mode (0=emulate TSC, 1=native TSC).""") +gopts.var('nomigrate', val='NOMIGRATE', + fn=set_int, default=0, + use="""migratability (0=migration enabled, 1=migration disabled).""") + gopts.var('vpt_align', val='VPT_ALIGN', fn=set_int, default=1, use="Enable aligning all periodic vpt to reduce timer interrupts.") @@ -737,6 +741,9 @@ def configure_image(vals): if vals.tsc_native is not None: config_image.append(['tsc_native', vals.tsc_native]) + if vals.nomigrate is not None: + config_image.append(['nomigrate', vals.nomigrate]) + return config_image def configure_disks(config_devs, vals): @@ -1020,7 +1027,7 @@ def make_config(vals): config.append([n, v]) map(add_conf, ['name', 'memory', 'maxmem', 'shadow_memory', - 'restart', 'on_poweroff', 'tsc_native', + 'restart', 'on_poweroff', 'tsc_native', 'nomigrate', 'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail', 'features', 'on_xend_start', 'on_xend_stop', 'target', 'cpuid', 'cpuid_check', 'machine_address_size', 'suppress_spurious_page_faults']) diff --git a/tools/python/xen/xm/xenapi_create.py b/tools/python/xen/xm/xenapi_create.py index 1f86357170..13e0af132f 100644 --- a/tools/python/xen/xm/xenapi_create.py +++ b/tools/python/xen/xm/xenapi_create.py @@ -1079,6 +1079,7 @@ class sxp2xml: 'xen_platform_pci', 'tsc_native' 'description', + 'nomigrate' ] platform_configs = [] diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 82ce975457..8b414a4ac7 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -522,6 +522,9 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags) spin_lock_init(&d->arch.vtsc_lock); + if ( d->domain_id == 0 ) + d->disable_migrate = 1; + return 0; fail: diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 581fcb3295..011e2d7112 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -1100,6 +1100,24 @@ long arch_do_domctl( } break; + case XEN_DOMCTL_disable_migrate: + { + struct domain *d; + + ret = -ESRCH; + d = rcu_lock_domain_by_id(domctl->domain); + if ( d == NULL ) + break; + + domain_pause(d); + d->arch.disable_migrate = domctl->u.disable_migrate.disable; + domain_unpause(d); + + rcu_unlock_domain(d); + ret = 0; + } + break; + case XEN_DOMCTL_suppress_spurious_page_faults: { struct domain *d; diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 08f2696ba9..851a71208d 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -304,6 +304,9 @@ struct arch_domain spinlock_t vtsc_lock; uint64_t vtsc_kerncount; /* for hvm, counts all vtsc */ uint64_t vtsc_usercount; /* not used for hvm */ + + /* mark domain as non-migratable and non-restoreable */ + bool_t disable_migrate; } __cacheline_aligned; #define has_arch_pdevs(d) (!list_empty(&(d)->arch.pdev_list)) diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index fb60344505..45337a6dae 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -653,6 +653,12 @@ typedef struct xen_domctl_hvmcontext_partial { } xen_domctl_hvmcontext_partial_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_partial_t); +#define XEN_DOMCTL_disable_migrate 58 +typedef struct xen_domctl_disable_migrate { + uint32_t disable; /* IN: 1: disable migration and restore */ +} xen_domctl_disable_migrate_t; + + #define XEN_DOMCTL_gdbsx_guestmemio 1000 /* guest mem io */ struct xen_domctl_gdbsx_memio { uint64_aligned_t pgd3val;/* optional: init_mm.pgd[3] value */ @@ -703,6 +709,7 @@ struct xen_domctl { struct xen_domctl_arch_setup arch_setup; struct xen_domctl_settimeoffset settimeoffset; struct xen_domctl_set_tsc_native set_tsc_native; + struct xen_domctl_disable_migrate disable_migrate; struct xen_domctl_real_mode_area real_mode_area; struct xen_domctl_hvmcontext hvmcontext; struct xen_domctl_hvmcontext_partial hvmcontext_partial; -- 2.30.2